package org.ftpscan;

import java.io.IOException;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.log4j.Logger;
import org.dom4j.Document;

/**
 * Main class of FTP scanning application.
 *
 * @author Nikolai Holub (nikolai.holub at gmail.com)
 */
public class FTPScan {
    private static Logger log =
        Logger.getLogger(FTPScan.class.getPackage().getName());

    /**
     * Arguments:
     * -h,--host         host
     * -d,--directory    directory
     * -x,--xml          XML result file
     * -s,--xsl          XSL file
     * -r,--result       result file
     *
     * @param args command line arguments
     */
    public static void main(String[] args) {
        CommandLineParser parser = new PosixParser();
        Options options = new Options();

        Option hostOption = new Option("h", "host", true, "host");
        hostOption.setRequired(true);

        options.addOption(hostOption);
        options.addOption("d", "directory", true, "directory");
        options.addOption("x", "xml", true, "XML result file");
        options.addOption("s", "xsl", true, "XSL file");
        options.addOption("r", "result", true, "result file");

        try {
            CommandLine line = parser.parse(options, args);

            // scan FTP directory
            FTPScanner ftpScan = new FTPScanner(
                line.getOptionValue("h"),
                line.getOptionValue("d", "/")
            );

            ftpScan.scan();

            // save results to XML file
            String xmlFileName = line.getOptionValue("x");

            if (xmlFileName != null) {
                saveXml(ftpScan.getXmlDocument(), xmlFileName);
            }

            // save results in transformed form
            String xslFileName = line.getOptionValue("s");
            String resFileName = line.getOptionValue("r");

            if (xmlFileName != null && resFileName != null) {
                transform(ftpScan.getXmlDocument(), xslFileName, resFileName);
            }
        } catch (ParseException e) {
            HelpFormatter formatter = new HelpFormatter();
            formatter.printHelp("FTPScan", options);
        } catch (Throwable e) {
            log.error("exception", e);
        }
    }

    /**
     * Saves XML document to the specified file.
     *
     * @param xmlDocument XMLDocument
     * @param fileName file name
     *
     * @see XMLDocument#save(String)
     */
    private static void saveXml(XMLDocument xmlDocument, String fileName) {
        try {
            xmlDocument.save(fileName);
        } catch (IOException e) {
            log.error("exception", e);
        }
    }

    /**
     * Transforms XML document.
     *
     * @param xmlDocument XMLDocument
     * @param xslFileName XSL file name
     * @param resFileName result file name
     *
     * @see XMLTransformer#transform(Document, String, String)
     */
    private static void transform(XMLDocument xmlDocument,
        String xslFileName, String resFileName) {

        try {
            Document document = xmlDocument.getDocument();
            XMLTransformer transformer = new XMLTransformer();

            transformer.transform(document, xslFileName, resFileName);
        } catch (Throwable e) {
            log.error("exception", e);
        }
    }
}
